#include "include/mucustomshortcuts.h"

#include <algorithm>
#include <functional>
#include <QSettings>
#include <QDebug>
#include <QRegExp>

namespace
{

	const QString ShortcutsGroup = "Shortcuts";

#define INIT_SHORTCUT(name) _shortcuts.push_back(name = new CustomShortcut(#name))

	bool tagIsEqual(const CustomShortcut* shortcut, const QString& tag)
	{
		return shortcut->tag() == tag;
	}

	void saveToSettings(const CustomShortcut* shortcut, QSettings* settings)
	{
		settings->setValue(shortcut->tag(), shortcut->sequence().toString());
	}

	CustomShortcut* findShortcut(const MuCustomShortcuts::Container& shortcuts, const QString& tag)
	{
		//TODO: make this search binary
		MuCustomShortcuts::Container::const_iterator it = std::find_if(shortcuts.begin(), shortcuts.end(), std::bind2nd(std::ptr_fun(tagIsEqual), tag));
		if (it == shortcuts.end())
			return 0;

		return *it;
	}

	bool tagIsLess(const CustomShortcut* sh1, const CustomShortcut* sh2)
	{
		return sh1->tag() < sh2->tag();
	}

}


MuCustomShortcuts::MuCustomShortcuts()
{
//	INIT_SHORTCUT(exitApplication);
//	INIT_SHORTCUT(saveKnowledgeTree);

//	INIT_SHORTCUT(insertKnowledgeTreeRow);
//	INIT_SHORTCUT(removeKnowledgeTreeRow);
//	INIT_SHORTCUT(insertKnowledgeTreeLeaf);
//	INIT_SHORTCUT(convertSelectionToCards);
//	INIT_SHORTCUT(pauseKnowledgeBranch);
//	INIT_SHORTCUT(unpauseKnowledgeBranch);
}


MuCustomShortcuts::~MuCustomShortcuts()
{
	qDeleteAll(_shortcuts);
}


CustomShortcut* MuCustomShortcuts::operator[](MuCustomShortcuts::size_type index) const
{
	return _shortcuts[index];
}

MuCustomShortcuts::size_type MuCustomShortcuts::size() const
{
	return _shortcuts.size();
}

void MuCustomShortcuts::add(QAction* action, const QString& tag)
{
	CustomShortcut* shortcut = new CustomShortcut(!tag.isEmpty() ? tag : action->text());
	_shortcuts.push_back(shortcut);
	shortcut->bindTo(action);
}

void MuCustomShortcuts::add(QShortcut* qshortcut, const QString& tag)
{
	CustomShortcut* shortcut = new CustomShortcut(!tag.isEmpty() ? tag : qshortcut->whatsThis());
	_shortcuts.push_back(shortcut);
	shortcut->bindTo(qshortcut);
}


void MuCustomShortcuts::sort()
{
	std::sort(_shortcuts.begin(), _shortcuts.end(), tagIsLess);
}


//void MuCustomShortcuts::bind(CustomShortcut* customShortcut, QAction* action)
//{
//	if (customShortcut == 0 || action == 0)
//		return;

//	customShortcut->bindTo(action);
//}


//void MuCustomShortcuts::bind(CustomShortcut* customShortcut, QShortcut* shortcut)
//{
//	if (customShortcut == 0 || shortcut == 0)
//		return;

//	customShortcut->bindTo(shortcut);
//}


void MuCustomShortcuts::setSequence(const QString& tag, const QKeySequence& sequence)
{
	//TODO make underlying collection sorted, use binary sech
	CustomShortcut* shortcut = findShortcut(_shortcuts, tag);
	if (shortcut == 0)
		return;

	shortcut->setSequence(sequence);
}


void MuCustomShortcuts::saveToSettings()
{
	QSettings settings;
	settings.beginGroup(ShortcutsGroup);
	std::for_each(_shortcuts.begin(), _shortcuts.end(), std::bind2nd(std::ptr_fun(::saveToSettings), &settings));
	settings.endGroup();
}

void MuCustomShortcuts::loadFromSettings()
{
	QSettings settings;

	settings.beginGroup(ShortcutsGroup);

	CustomShortcut* shortcut = 0;
	foreach (shortcut, _shortcuts)
	{
		QVariant v = settings.value(shortcut->tag());
		if (!v.isValid())
			continue;

		QKeySequence seq(v.toString());
		shortcut->setSequence(seq);
	}

	settings.endGroup();
}



